package cn.lingyangwl.agile.demo.mq_sequence;

import cn.lingyangwl.framework.tool.core.exception.BizException;
import lombok.AllArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 当前序号, 只能被一个上一个序号枚举作为下一个序号
 * 序号要递增, 目前只支持连续的序号
 * @author shenguangyang
 */
@AllArgsConstructor
public enum TestConsumeRule implements IConsumeRule {
    A(1, of(2)),
    B(2, of(3)),
    C(3, of(4)),
    D(4, of(5, 6, 7)),
    E(5, Collections.emptyList()),
    F(6, of(7)),
    G(7, Collections.emptyList()),
    ;
    private final Integer currentNo;
    private final List<Integer> nextNoList;


    private static List<Integer> of(Integer... no) {
        return Arrays.stream(no).collect(Collectors.toList());
    }

    public static IConsumeRule getStartRule() {
        return Arrays.stream(values()).min(Comparator.comparing(TestConsumeRule::getCurrentNo))
                .orElseThrow(() -> new BizException("数据为空"));
    }

    @Override
    public Integer getCurrentNo() {
        return currentNo;
    }


    /**
     * 通过上前号获取前一个序号
     */
    public static IConsumeRule getPreRule(Integer currentNo) {
        IConsumeRule start = getStartRule();
        if (getStartRule().getCurrentNo().compareTo(currentNo) == 0) {
            return start;
        }
        return Arrays.stream(values()).filter(e -> e.nextNoList.contains(currentNo)).findFirst()
                .orElseThrow(() -> new BizException("未查询到上一个序号, currentNo: {}", currentNo));
    }

    /**
     * 获取所有孩子号
     */
    public static Set<Integer> listAllNextNo(List<Integer> currentNoList) {
        List<Integer> noList = Arrays.stream(values()).filter(e -> currentNoList.contains(e.getCurrentNo()))
                .map(TestConsumeRule::getNextNoList).flatMap(Collection::stream)
                .collect(Collectors.toList());
        return Arrays.stream(values()).map(TestConsumeRule::getCurrentNo)
                .filter(noList::contains).collect(Collectors.toSet());
    }


    public static IConsumeRule ofByCurrentNo(Integer currentNo) {
        return Arrays.stream(values()).filter(e -> e.getCurrentNo().compareTo(currentNo) == 0).findFirst()
                .orElseThrow(() -> new RuntimeException("未查询到序号"));
    }

    @Override
    public List<Integer> getNextNoList() {
        return nextNoList;
    }
}
